var _n25;
var cc__extends = __extends;
var cc__decorate = __decorate;
Object.defineProperty(exports, "__esModule", {
  value: true
});
var a = function a() {
  this.x = 0;
  this.y = 0;
  this.dis = 0;
  this.cos = 0;
  this.sin = 0;
};
var cc__decorator = cc._decorator;
var ccp_ccclass = cc__decorator.ccclass;
var ccp_property = cc__decorator.property;
var ccp_playOnFocus = cc__decorator.playOnFocus;
var ccp_menu = cc__decorator.menu;
var def_MotionTrail = function (t) {
  function _ctor() {
    // 调用父类构造函数并确保返回当前上下文
    var instance = null !== t && t.apply(this, arguments) || this;

    // 设置自定义绘制的基本属性
    instance.atlas = null;                 // 纹理图集
    instance._spriteFrame = null;          // 精灵帧
    instance._isActive = true;              // 是否处于激活状态
    instance._isWorldXY = true;            // 坐标系是否使用世界坐标
    instance.offset = cc.v2(0, 0);         // 偏移量
    instance._length = 20;                  // 绘制长度
    instance._headWidth = 100;              // 头部宽度
    instance._tailWidth = 0;                // 尾部宽度
    instance._headOpacity = 255;            // 头部不透明度
    instance._tailOpacity = 0;              // 尾部不透明度
    instance.renderData = null;             // 渲染数据
    instance.xyOffset = 1e8;                // XY偏移
    instance.uvOffset = 1e8;                // UV偏移
    instance.colorOffset = 1e8;             // 颜色偏移
    instance.step = 0;                      // 当前步骤
    instance.joints = [];                   // 连接点数组
    instance.cascadeScale = cc.v2(1, 1);    // 级联缩放
    instance.visibleScale = cc.v2(1, 1);    // 可见缩放

    // 返回创建的实例
    return instance;

  }
  cc__extends(_ctor, t);
  Object.defineProperty(_ctor.prototype, "spriteFrame", {
    get() {
      return this._spriteFrame;
    },
    set(t) {
      this._spriteFrame = t;
      this.updateSpriteFrame();
      this.updateUV();
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "isActive", {
    get() {
      return this._isActive;
    },
    set(t) {
      this._isActive = this.enabled = t;
      this.updateActive();
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "isWorldXY", {
    get() {
      return this._isWorldXY;
    },
    set(t) {
      this._isWorldXY = t;
      this.resetPos();
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "length", {
    get() {
      return this._length;
    },
    set(t) {
      this._length = Math.max(t, 2);
      this.updateLength();
      this.updateIndice();
      this.updateUV();
      this.updateWidth();
      this.resetPos();
      this.node._renderFlag |= cc.RenderFlow.FLAG_OPACITY_COLOR;
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "headWidth", {
    get() {
      return this._headWidth;
    },
    set(t) {
      this._headWidth = Math.max(t, 0);
      this.updateWidth();
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "tailWidth", {
    get() {
      return this._tailWidth;
    },
    set(t) {
      this._tailWidth = Math.max(t, 0);
      this.updateWidth();
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "headOpacity", {
    get() {
      return this._headOpacity;
    },
    set(t) {
      this._headOpacity = t;
      this.node._renderFlag |= cc.RenderFlow.FLAG_OPACITY_COLOR;
    },
    enumerable: false,
    configurable: true
  });
  Object.defineProperty(_ctor.prototype, "tailOpacity", {
    get() {
      return this._tailOpacity;
    },
    set(t) {
      this._tailOpacity = t;
      this.node._renderFlag |= cc.RenderFlow.FLAG_OPACITY_COLOR;
    },
    enumerable: false,
    configurable: true
  });
  _ctor.prototype._resetAssembler = function () {
    // 创建新的 assembler 实例
    var assembler = this._assembler = new cc.Assembler();

    // 绑定更新数据的方法
    assembler.updateRenderData = this.updateXY.bind(this);
    assembler.updateColor = this.updateColor.bind(this);
    this.update = this.setVertsDirty; // 设置更新方法

    // 初始化 assembler
    assembler.init(this);

    // 创建和初始化渲染数据
    this.renderData = new cc.RenderData();
    this.renderData.init(assembler);

    // 获取顶点格式并计算偏移量
    var vertexFormat = assembler.getVfmt();
    var elements = vertexFormat._elements;

    // 计算当前步数
    for (var i = elements.length - 1; i > -1; this.step += elements[i--].bytes >> 2) {
      // 仅用于计算步骤，空语句
    }

    // 提取属性到元素的映射
    var attrToElement = vertexFormat._attr2el;
    this.xyOffset = attrToElement.a_position.offset >> 2; // 位置偏移
    this.uvOffset = attrToElement.a_uv0.offset >> 2;      // UV 偏移
    this.colorOffset = attrToElement.a_color.offset >> 2;  // 颜色偏移

  };
  _ctor.prototype.onLoad = function () {
    this.updateSpriteFrame();
    this.updateLength();
    this.updateIndice();
    this.updateUV();
    this.updateWidth();
    this.updateActive();
    cc.sys.isNative && cc.director.once(cc.Director.EVENT_AFTER_DRAW, this.updateColor, this);
    this.node.on(cc.Node.EventType.SCALE_CHANGED, this.updateVisibleScale, this);
  };
  _ctor.prototype.onDestroy = function () {
    this.node.off(cc.Node.EventType.SCALE_CHANGED, this.updateVisibleScale, this);
  };
  _ctor.prototype.updateActive = function () {
    if (this._isActive) {
      this.updateCascadeScale();
      this.updateVisibleScale();
      this.resetPos();
    }
  };
  _ctor.prototype.createBuffer = function (t, e) {
    // 如果 e 未定义，设置为 t - 2
    if (e === undefined) {
      e = t - 2;
    }

    // 创建浮点数数组，大小为步数乘以 t
    var floatArray = new Float32Array(this.step * t);

    // 创建无符号短整型数组，大小为 3 乘以 e
    var uintArray = new Uint16Array(3 * e);

    // 更新渲染数据的网格
    this.renderData.updateMesh(0, floatArray, uintArray);

  };
  _ctor.prototype.fillBuffers = function (t, e) {
    var vertexData = this.renderData.vDatas[0]; // 获取顶点数据
    var indexData = this.renderData.iDatas[0];   // 获取索引数据
    var meshBuffer = e._meshBuffer;               // 获取网格缓冲区
    var request = meshBuffer.request(vertexData.length, indexData.length); // 请求缓冲区的空间

    var byteOffset = request.byteOffset >> 2;    // 计算字节偏移量
    var vertexArray = meshBuffer._vData;          // 获取顶点数组

    // 检查顶点长度，确定数据填充方式
    if (vertexData.length + byteOffset > vertexArray.length) {
      vertexArray.set(vertexData.subarray(0, vertexArray.length - byteOffset), byteOffset);
    } else {
      vertexArray.set(vertexData, byteOffset); // 填充顶点数据
    }

    var indexArray = meshBuffer._iData; // 获取索引数组
    var indicesOffset = request.indiceOffset; // 获取索引偏移量
    var verticesOffset = request.vertexOffset; // 获取顶点偏移量
    var index = 0;

    // 填充索引数组
    for (var length = indexData.length; index < length; index++) {
      indexArray[indicesOffset++] = verticesOffset + indexData[index]; // 更新索引值
    }

  };
  _ctor.prototype.updateSpriteFrame = function () {
    var spriteFrame = this._spriteFrame; // 获取当前的精灵帧

    // 设置填充缓冲区方法，如果精灵帧存在则绑定方法，否则设置为空函数
    this._assembler.fillBuffers = spriteFrame ? this.fillBuffers.bind(this) : function () { };

    // 获取材质，如果没有则使用内置的2D精灵材质
    var material = this.getMaterial(0) || cc.Material.getBuiltinMaterial("2d-sprite");

    // 定义材质的属性
    material.define("USE_TEXTURE", true); // 启用纹理使用
    material.setProperty("texture", spriteFrame ? spriteFrame.getTexture() : null); // 设置纹理

  };
  _ctor.prototype.updateCascadeScale = function () {
    var currentNode = this.node; // 获取当前节点
    var scaleX = 1; // 初始化X轴缩放因子
    var scaleY = 1; // 初始化Y轴缩放因子

    // 遍历所有父节点，累积缩放值
    while (currentNode._parent !== null) {
      currentNode = currentNode._parent; // 移动到父节点
      scaleX *= currentNode.scaleX; // 累乘X轴缩放
      scaleY *= currentNode.scaleY; // 累乘Y轴缩放
    }

    // 设置级联缩放
    this.cascadeScale.x = scaleX;
    this.cascadeScale.y = scaleY;

  };
  _ctor.prototype.updateVisibleScale = function () {
    this.visibleScale.x = this.cascadeScale.x * this.node.scaleX;
    this.visibleScale.y = this.cascadeScale.y * this.node.scaleY;
  };
  _ctor.prototype.updateXY = function () {
    var currentNode = this.node; // 获取当前节点
    var joints = this.joints; // 获取关节数据

    // 倒序遍历关节更新位置和角度
    for (var i = this._length - 1; i > 0; --i) {
      var currentJoint = joints[i];
      var previousJoint = joints[i - 1];
      currentJoint.x = previousJoint.x; // 复制位置
      currentJoint.y = previousJoint.y;
      currentJoint.sin = previousJoint.sin; // 复制正弦和余弦
      currentJoint.cos = previousJoint.cos;
    }

    var firstJoint = joints[0];
    var secondJoint = joints[1];
    var visibleScaleX = this.visibleScale.x;
    var visibleScaleY = this.visibleScale.y;

    // 计算世界坐标或局部坐标
    if (this._isWorldXY) {
      var worldMatrix = currentNode._worldMatrix.m; // 获取世界矩阵
      firstJoint.x = this.offset.x * visibleScaleX + worldMatrix[12];
      firstJoint.y = this.offset.y * visibleScaleY + worldMatrix[13];
    } else {
      firstJoint.x = this.offset.x * currentNode.scaleX + currentNode.x; // 局部坐标计算
      firstJoint.y = this.offset.y * currentNode.scaleY + currentNode.y;
    }

    // 计算第一和第二关节的位移
    var dy = secondJoint.y - firstJoint.y;
    var dx = secondJoint.x - firstJoint.x;
    var distance = Math.sqrt(dy * dy + dx * dx); // 计算距离
    firstJoint.sin = dy / distance; // 计算正弦
    firstJoint.cos = dx / distance; // 计算余弦

    var renderData = this.renderData.vDatas[0]; // 获取渲染数据
    var index = 0; // 初始化索引

    // 计算缩放因子
    var offsetX = 0, offsetY = 0, scaleX = 1, scaleY = 1;
    if (!this._isWorldXY) {
      offsetX = currentNode.x; // 获取局部坐标
      offsetY = currentNode.y;
      scaleX = this.cascadeScale.x; // 获取级联缩放
      scaleY = this.cascadeScale.y;
    }

    // 遍历关节更新渲染数据
    for (var j = 0; j < this._length - 1; ++j) {
      var joint = joints[j];
      var nextJoint = joints[j + 1];

      // 计算每个关节的渲染数据
      var scaledX = (joint.x - offsetX) * scaleX;
      var scaledY = (joint.y - offsetY) * scaleY;
      var offsetSin = joint.dis * visibleScaleX * joint.sin;
      var offsetCos = joint.dis * visibleScaleY * joint.cos;

      renderData[index] = scaledX + offsetSin; // 更新渲染数据
      renderData[index + 1] = scaledY - offsetCos;
      index += this.step; // 更新索引

      // 处理与下一个关节的关系
      renderData[index] = scaledX - offsetSin;
      renderData[index + 1] = scaledY + offsetCos;
      index += this.step; // 更新索引
    }

    // 处理最后一个关节的渲染数据
    scaledX = (nextJoint.x - offsetX) * scaleX;
    scaledY = (nextJoint.y - offsetY) * scaleY;
    offsetSin = nextJoint.dis * visibleScaleX * firstJoint.sin;
    offsetCos = nextJoint.dis * visibleScaleY * firstJoint.cos;

    renderData[index] = scaledX + offsetSin; // 更新渲染数据
    renderData[index + 1] = scaledY - offsetCos;
    index += this.step; // 更新索引

    renderData[index] = scaledX - offsetSin;
    renderData[index + 1] = scaledY + offsetCos;

    // 调整坐标
    this.fitXY(renderData);

  };
  _ctor.prototype.resetPos = function () {
    var offsetX = this.offset.x; // 获取X偏移
    var offsetY = this.offset.y; // 获取Y偏移
    var node = this.node; // 获取当前节点

    // 根据是否使用世界坐标系调整偏移
    if (this._isWorldXY) {
      var worldMatrix = node._worldMatrix.m; // 获取世界矩阵
      node._updateWorldMatrix(); // 更新世界矩阵
      offsetX += worldMatrix[12]; // 更新X偏移
      offsetY += worldMatrix[13]; // 更新Y偏移
    } else {
      offsetX += node.x; // 局部坐标计算
      offsetY += node.y;
    }

    // 更新关节位置
    var length = this._length - 1; // 获取关节的长度
    for (var joints = this.joints; length > -1; --length) {
      joints[length].x = offsetX; // 设置关节X坐标
      joints[length].y = offsetY; // 设置关节Y坐标
    }

    // 更新渲染数据坐标
    var renderData = this.renderData.vDatas[0]; // 获取渲染数据
    var offsetIndex = this.xyOffset; // 获取坐标偏移
    var dataLength = renderData.length; // 渲染数据长度

    // 填充渲染数据坐标
    for (var step = this.step; offsetIndex < dataLength; offsetIndex += step) {
      renderData[offsetIndex] = offsetX; // 设置渲染数据X坐标
      renderData[offsetIndex + 1] = offsetY; // 设置渲染数据Y坐标
    }

    // 调整坐标
    this.fitXY(renderData);

  };
  _ctor.prototype.fitXY = function (t) {
    // 如果当前环境为原生平台
    if (cc.sys.isNative) {
      this.node._updateWorldMatrix(); // 更新节点的世界矩阵

      // 计算世界矩阵的逆矩阵
      var invertedMatrix = cc.Mat4.invert(new cc.Mat4(), this.node._worldMatrix).m;
      var scaleX = invertedMatrix[0]; // 反转矩阵的X缩放
      var scaleY = invertedMatrix[1]; // 反转矩阵的Y缩放
      var translateX = invertedMatrix[12]; // 反转矩阵的平移X
      var translateY = invertedMatrix[13]; // 反转矩阵的平移Y

      // 初始化偏移量
      var offsetX = 0;
      var offsetY = 0;

      // 如果使用世界坐标
      if (this._isWorldXY) {
        offsetX = translateX; // 使用翻转矩阵的平移X
        offsetY = translateY; // 使用翻转矩阵的平移Y
      }

      var xyOffset = this.xyOffset; // 获取坐标偏移
      for (var length = t.length; xyOffset < length; xyOffset += this.step) {
        var vertexX = t[xyOffset]; // 顶点X
        var vertexY = t[xyOffset + 1]; // 顶点Y
        // 计算新的顶点位置
        t[xyOffset] = scaleX * vertexX + invertedMatrix[4] * vertexY + offsetX;
        t[xyOffset + 1] = scaleY * vertexX + invertedMatrix[5] * vertexY + offsetY;
      }
    } else if (!this._isWorldXY) {
      // 如果不是世界坐标系统
      var worldMatrix = this.node._worldMatrix.m; // 获取世界矩阵
      offsetX = worldMatrix[12]; // 获取平移X
      offsetY = worldMatrix[13]; // 获取平移Y
      var xyOffset = this.xyOffset; // 获取坐标偏移
      for (var length = t.length; xyOffset < length; xyOffset += this.step) {
        // 更新顶点坐标
        t[xyOffset] += offsetX; // 更新X坐标
        t[xyOffset + 1] += offsetY; // 更新Y坐标
      }
    }

  };
  _ctor.prototype.updateUV = function () {
    var vertexData = this.renderData.vDatas[0]; // 获取顶点数据
    var step = this.step; // 步长
    var jointCount = this.joints.length - 1; // 关节数量
    var uvOffset = this.uvOffset; // UV坐标偏移
    var index = 0; // 初始化索引

    // 计算UV坐标
    var length = vertexData.length; // 顶点数据长度
    for (; uvOffset < length; uvOffset += step, ++index) {
      vertexData[uvOffset] = 1 & index; // UV的X坐标（交替设置为0或1）
      vertexData[uvOffset + 1] = 1 - (index >> 1) * (1 / jointCount); // 计算UV的Y坐标
    }

    // 适配UV坐标
    this.fitUV(vertexData);
  };
  _ctor.prototype.fitUV = function (t) {
    var spriteFrame = this._spriteFrame; // 获取当前精灵帧

    // 检查精灵帧是否存在
    if (spriteFrame !== null) {
      var textureWidth = spriteFrame._texture.width; // 获取纹理宽度
      var textureHeight = spriteFrame._texture.height; // 获取纹理高度
      var rect = spriteFrame._rect; // 获取纹理的矩形区域

      // 处理旋转情况
      if (spriteFrame._rotated) {
        var uvOffset = this.uvOffset; // 获取UV偏移
        var length = t.length; // 顶点数据长度
        for (var step = this.step; uvOffset < length; uvOffset += step) {
          var currentY = t[uvOffset + 1]; // 当前Y值
          t[uvOffset] = ((1 - currentY) * rect.height + rect.x) / textureWidth; // 更新X坐标
          t[uvOffset + 1] = (t[uvOffset] * rect.width + rect.y) / textureHeight; // 更新Y坐标
        }
      } else { // 处理未旋转的情况
        var uvOffset = this.uvOffset; // 获取UV偏移
        var length = t.length; // 顶点数据长度
        for (var step = this.step; uvOffset < length; uvOffset += step) {
          t[uvOffset] = (t[uvOffset] * rect.width + rect.x) / textureWidth; // 更新X坐标
          t[uvOffset + 1] = (t[uvOffset + 1] * rect.height + rect.y) / textureHeight; // 更新Y坐标
        }
      }
    }

  };
  _ctor.prototype.updateColor = function () {
    // 更新颜色渲染数据
    var length = this._length; // 获取长度
    var headOpacity = this._headOpacity; // 获取头部不透明度
    var tailOpacity = this._tailOpacity; // 获取尾部不透明度
    var opacityStep = (headOpacity - tailOpacity) / (length - 1); // 计算不透明度变化步长
    var alpha = this.node.color.a / 255; // 获取节点的透明度
    var colorValue = 16777215 & this.node.color._val; // 提取颜色值（RGBA）

    var renderData = this.renderData.uintVDatas[0]; // 获取渲染数据
    var offset = this.colorOffset; // 获取颜色偏移

    // 更新颜色数据
    for (var index = 0; index < length; ++index) {
      var currentOpacity = (headOpacity - opacityStep * index) * alpha << 24 | colorValue; // 计算当前颜色值
      renderData[offset] = currentOpacity; // 更新渲染数据
      renderData[offset += this.step] = currentOpacity; // 更新渲染数据
      offset += this.step; // 移动到下一个位置
    }
  };
  _ctor.prototype.updateIndice = function () {
    var indexData = this.renderData.iDatas[0]; // 获取索引数据
    var index = 0; // 初始化索引
    var offset = 0; // 用于遍历索引数据

    // 更新索引数据
    for (var length = indexData.length; offset < length; ++index) {
      indexData[offset++] = index;      // 设置当前索引
      indexData[offset++] = index + 1;  // 设置下一个索引
      indexData[offset++] = index + 2;  // 设置下下一个索引
    }
  };
  _ctor.prototype.updateLength = function () {
    var length = this._length; // 获取关节长度
    var index = 0; // 初始化索引

    // 初始化关节数组
    this.joints = [];
    for (; index < length; index++) {
      this.joints[index] = new a(); // 创建新的关节实例
    }

    // 创建缓冲区，大小为关节数的两倍
    this.createBuffer(length << 1); // 使用位移运算符计算缓冲区大小
  };
  _ctor.prototype.updateWidth = function () {
    // 更新关节的距离属性
    var length = this._length; // 获取关节的数量
    var headWidth = 0.5 * this._headWidth; // 头部宽度的一半
    var tailWidth = 0.5 * this._tailWidth; // 尾部宽度的一半
    var distanceStep = (headWidth - tailWidth) / (length - 1); // 计算距离变化步长
    var index = 0; // 初始化索引

    // 更新每个关节的距离属性
    for (var joints = this.joints; index < length; index++) {
      joints[index].dis = headWidth - distanceStep * index; // 计算并设置 distance
    }
  };
  cc__decorate([ccp_property({
    type: cc.SpriteAtlas,
    serializable: false,
    readonly: true,
    // displayName: false
  })], _ctor.prototype, "atlas", undefined);
  cc__decorate([ccp_property], _ctor.prototype, "_spriteFrame", undefined);
  cc__decorate([ccp_property({
    type: cc.SpriteFrame,
    // displayName: false
  })], _ctor.prototype, "spriteFrame", null);
  cc__decorate([ccp_property], _ctor.prototype, "_isActive", undefined);
  cc__decorate([ccp_property({
    // displayName: false,
    // tooltip: false
  })], _ctor.prototype, "isActive", null);
  cc__decorate([ccp_property], _ctor.prototype, "_isWorldXY", undefined);
  cc__decorate([ccp_property({
    // displayName: false,
    // tooltip: false
  })], _ctor.prototype, "isWorldXY", null);
  cc__decorate([ccp_property({
    // displayName: false
  })], _ctor.prototype, "offset", undefined);
  cc__decorate([ccp_property], _ctor.prototype, "_length", undefined);
  cc__decorate([ccp_property({
    type: cc.Integer,
    // displayName: false
  })], _ctor.prototype, "length", null);
  cc__decorate([ccp_property], _ctor.prototype, "_headWidth", undefined);
  cc__decorate([ccp_property({
    // displayName: false
  })], _ctor.prototype, "headWidth", null);
  cc__decorate([ccp_property], _ctor.prototype, "_tailWidth", undefined);
  cc__decorate([ccp_property({
    // displayName: false
  })], _ctor.prototype, "tailWidth", null);
  cc__decorate([ccp_property], _ctor.prototype, "_headOpacity", undefined);
  cc__decorate([ccp_property({
    type: cc.Integer,
    min: 0,
    max: 255,
    slide: true,
    // displayName: false
  })], _ctor.prototype, "headOpacity", null);
  cc__decorate([ccp_property], _ctor.prototype, "_tailOpacity", undefined);
  cc__decorate([ccp_property({
    type: cc.Integer,
    min: 0,
    max: 255,
    slide: true,
    // displayName: false
  })], _ctor.prototype, "tailOpacity", null);
  return cc__decorate([ccp_ccclass, ccp_playOnFocus, ccp_menu("Comp/MotionTrail")], _ctor);
}(cc.RenderComponent);
exports.default = def_MotionTrail;